home *** CD-ROM | disk | FTP | other *** search
/ The Atari Compendium / The Atari Compendium (Toad Computers) (1994).iso / files / prgtools / gnustuff / tos / futils / futils~1 / src / file31s.zoo / file3.1 / lib / fsinfo.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-11-02  |  10.1 KB  |  447 lines

  1. /* fsinfo.c -- return info about mounted filesystems
  2.    Copyright (C) 1991 Free Software Foundation, Inc.
  3.  
  4.    This program is free software; you can redistribute it and/or modify
  5.    it under the terms of the GNU General Public License as published by
  6.    the Free Software Foundation; either version 2, or (at your option)
  7.    any later version.
  8.  
  9.    This program is distributed in the hope that it will be useful,
  10.    but WITHOUT ANY WARRANTY; without even the implied warranty of
  11.    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12.    GNU General Public License for more details.
  13.  
  14.    You should have received a copy of the GNU General Public License
  15.    along with this program; if not, write to the Free Software
  16.    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
  17.  
  18. #include <stdio.h>
  19. #include <sys/types.h>
  20. #include <errno.h>
  21. #include "fsinfo.h"
  22.  
  23. /**
  24.  ** (sjk)++ We need osbind for the hacked fs info data.
  25.  **/
  26. #if defined(__atarist__)
  27. #include <osbind.h>
  28. #endif
  29.  
  30. #ifdef STDC_HEADERS
  31. #include <stdlib.h>
  32. #else
  33. extern int errno;
  34. void exit ();
  35. void free ();
  36. #endif
  37. #if defined(USG) || defined(STDC_HEADERS)
  38. #include <string.h>
  39. #else
  40. #include <strings.h>
  41. #endif
  42.  
  43. int statfs ();
  44.  
  45. int xatoi ();
  46. char *strstr ();
  47. char *xmalloc ();
  48. char *xrealloc ();
  49. char *xstrdup ();
  50. void error ();
  51.  
  52. #ifdef FS_MNTENT
  53. #include <sys/vfs.h>
  54. #include <mntent.h>
  55. #if !defined(MOUNTED) && defined(MNT_MNTTAB) /* HP-UX. */
  56. #define MOUNTED MNT_MNTTAB
  57. #endif
  58. #endif /* FS_MNTENT */
  59.  
  60. #ifdef FS_GETMNT
  61. #include <sys/param.h>
  62. #include <sys/mount.h>
  63. #include <sys/fs_types.h>
  64. int getmnt ();
  65. #endif
  66.  
  67. #ifdef FS_USG_STATFS
  68. #include <mnttab.h>
  69. #include <sys/statfs.h>
  70. #include <sys/fstyp.h>
  71. #endif
  72.  
  73. #ifdef FS_STATVFS
  74. #include <sys/statvfs.h>
  75. #include <sys/mnttab.h>
  76. #endif
  77.  
  78. #ifdef FS_STATFS
  79. #include <sys/mount.h>
  80.  
  81. char *
  82. fstype_to_string (t)
  83.      short t;
  84. {
  85.   switch (t)
  86.     {
  87.     case MOUNT_UFS:
  88.       return "ufs";
  89.     case MOUNT_NFS:
  90.       return "nfs";
  91.     case MOUNT_PC:
  92.       return "pc";
  93. #ifdef MOUNT_MFS
  94.     case MOUNT_MFS:
  95.       return "mfs";
  96. #endif
  97. #ifdef MOUNT_LO
  98.     case MOUNT_LO:
  99.       return "lo";
  100. #endif
  101. #ifdef MOUNT_TFS
  102.     case MOUNT_TFS:
  103.       return "tfs";
  104. #endif
  105. #ifdef MOUNT_TMP
  106.     case MOUNT_TMP:
  107.       return "tmp";
  108. #endif
  109.     default:
  110.       return "?";
  111.     }
  112. }
  113. #endif
  114.  
  115. /* Return a list of the currently mounted filesystems, or NULL on error.
  116.    Add each entry to the tail of the list so that they stay in order.
  117.    If NEED_FS_TYPE is nonzero, make sure the filesystem type fields in
  118.    the returned list are valid. */
  119.  
  120. struct mount_entry *
  121. read_filesystem_list (need_fs_type)
  122.      int need_fs_type;
  123. {
  124.   struct mount_entry *mount_list;
  125.   struct mount_entry *me;
  126.   struct mount_entry *mtail;
  127.  
  128.   /* Start the list off with a dummy entry. */
  129.   me = (struct mount_entry *) xmalloc (sizeof (struct mount_entry));
  130.   if (me <= NULL)
  131.     { puts("xmalloc() failed, exiting..."); exit(0);
  132.     }
  133.   me->me_next = NULL;
  134.   mount_list = mtail = me;
  135.  
  136. /**
  137.  ** (sjk)++ Build a psuedo mount table of available disk devices.
  138.  **/
  139. #if defined(__atarist__)
  140. {  int mount_flags,drive,dev;
  141.    drive = 2;  
  142.    mount_flags = Drvmap();
  143.    mount_flags = mount_flags>>2;     /* Get rid of /dev/A and /dev/B */
  144.    while (mount_flags != 0)
  145.      { dev = mount_flags%2; 
  146.        if (dev == 1)
  147.          { me = (struct mount_entry *) xmalloc (sizeof (struct mount_entry));
  148.            me->me_devname = xstrdup("/dev/X");
  149.            me->me_devname[5] = (char)(drive+'A');
  150.            me->me_mountdir = xstrdup("X:");
  151.        me->me_mountdir[0] = (char)(drive+'A');
  152.            me->me_type =  xstrdup("STfs");
  153.            me->me_dev = drive;
  154.            me->me_next = NULL;
  155.            mtail->me_next = me;        mtail = me;
  156.      }
  157.        drive++;
  158.        mount_flags = mount_flags>>1;
  159.      }
  160.  }
  161. #else 
  162. #ifdef FS_MNTENT        /* 4.3BSD, SunOS, HP-UX */
  163.   {
  164.     struct mntent *mnt;
  165.     char *table = MOUNTED;    /* /etc/mtab, usually. */
  166.     FILE *fp;
  167.     char *devopt;
  168.  
  169.     fp = setmntent (table, "r");
  170.     if (fp == NULL)
  171.       return NULL;
  172.  
  173.     while ((mnt = getmntent (fp)))
  174.       {
  175.     me = (struct mount_entry *) xmalloc (sizeof (struct mount_entry));
  176.     me->me_devname = xstrdup (mnt->mnt_fsname);
  177.     me->me_mountdir = xstrdup (mnt->mnt_dir);
  178.     me->me_type = xstrdup (mnt->mnt_type);
  179.     devopt = strstr (mnt->mnt_opts, "dev=");
  180.     if (devopt)
  181.       {
  182.         if (devopt[4] == '0' && (devopt[5] == 'x' || devopt[5] == 'X'))
  183.           me->me_dev = xatoi (devopt + 6);
  184.         else
  185.           me->me_dev = xatoi (devopt + 4);
  186.       }
  187.     else
  188.       me->me_dev = -1;    /* Magic; means not known yet. */
  189.     me->me_next = NULL;
  190.  
  191.     /* Add to the linked list. */
  192.     mtail->me_next = me;
  193.     mtail = me;
  194.       }
  195.  
  196.     if (endmntent (fp) == 0)
  197.       return NULL;
  198.   }
  199. #endif /* FS_MNTENT */
  200.  
  201. #ifdef FS_GETMNT        /* Ultrix */
  202.   {
  203.     int offset = 0;
  204.     int val;
  205.     struct fs_data fsd;
  206.  
  207.     while ((val = getmnt (&offset, &fsd, sizeof (fsd), NOSTAT_MANY,
  208.               (char *) 0)) > 0)
  209.       {
  210.     me = (struct mount_entry *) xmalloc (sizeof (struct mount_entry));
  211.     me->me_devname = xstrdup (fsd.fd_req.devname);
  212.     me->me_mountdir = xstrdup (fsd.fd_req.path);
  213.     me->me_type = gt_names[fsd.fd_req.fstype];
  214.     me->me_dev = fsd.fd_req.dev;
  215.     me->me_next = NULL;
  216.  
  217.     /* Add to the linked list. */
  218.     mtail->me_next = me;
  219.     mtail = me;
  220.       }
  221.     if (val < 0)
  222.       return NULL;
  223.   }
  224. #endif /* FS_GETMNT */
  225.  
  226. #ifdef FS_USG_STATFS        /* SVR3.2 */
  227.   {
  228.     struct mnttab mnt;
  229.     char *table = "/etc/mnttab";
  230.     FILE *fp;
  231.  
  232.     fp = fopen (table, "r");
  233.     if (fp == NULL)
  234.       return NULL;
  235.  
  236.     while (fread (&mnt, sizeof mnt, 1, fp) > 0)
  237.       {
  238.     me = (struct mount_entry *) xmalloc (sizeof (struct mount_entry));
  239.     me->me_devname = xstrdup (mnt.mt_dev);
  240.     me->me_mountdir = xstrdup (mnt.mt_filsys);
  241.     me->me_dev = -1;    /* Magic; means not known yet. */
  242.     me->me_type = "";
  243.     if (need_fs_type)
  244.       {
  245.         struct statfs fsd;
  246.         char typebuf[FSTYPSZ];
  247.  
  248.         if (statfs (me->me_mountdir, &fsd, sizeof fsd, 0) != -1
  249.         && sysfs (GETFSTYP, fsd.f_fstyp, typebuf) != -1)
  250.           me->me_type = xstrdup (typebuf);
  251.       }
  252.     me->me_next = NULL;
  253.  
  254.     /* Add to the linked list. */
  255.     mtail->me_next = me;
  256.     mtail = me;
  257.       }
  258.  
  259.     if (fclose (fp) == EOF)
  260.       return NULL;
  261.   }
  262. #endif /* FS_USG_STATFS */
  263.  
  264. #ifdef FS_STATVFS        /* SVR4 */
  265.   {
  266.     struct mnttab mnt;
  267.     char *table = MNTTAB;
  268.     FILE *fp;
  269.     int ret;
  270.  
  271.     fp = fopen (table, "r");
  272.     if (fp == NULL)
  273.       return NULL;
  274.  
  275.     while ((ret = getmntent (fp, &mnt)) == 0)
  276.       {
  277.     me = (struct mount_entry *) xmalloc (sizeof (struct mount_entry));
  278.     me->me_devname = xstrdup (mnt.mnt_special);
  279.     me->me_mountdir = xstrdup (mnt.mnt_mountp);
  280.     me->me_type = xstrdup (mnt.mnt_fstype);
  281.     me->me_dev = -1;    /* Magic; means not known yet. */
  282.     me->me_next = NULL;
  283.  
  284.     /* Add to the linked list. */
  285.     mtail->me_next = me;
  286.     mtail = me;
  287.       }
  288.  
  289.     if (ret > 0)
  290.       return NULL;
  291.    if (fclose (fp) == EOF)
  292.       return NULL;
  293.   }
  294. #endif
  295.  
  296. #ifdef FS_STATFS        /* 4.4BSD */
  297.   {
  298.     struct statfs *fsp;
  299.     int entries;
  300.  
  301.     entries = getmntinfo (&fsp, MNT_NOWAIT);
  302.     if (entries < 0)
  303.       return NULL;
  304.     while (entries-- > 0)
  305.       {
  306.     me = (struct mount_entry *) xmalloc (sizeof (struct mount_entry));
  307.     me->me_devname = xstrdup (fsp->f_mntfromname);
  308.     me->me_mountdir = xstrdup (fsp->f_mntonname);
  309.     me->me_type = fstype_to_string (fsp->f_type);
  310.     me->me_dev = -1;    /* Magic; means not known yet. */
  311.     me->me_next = NULL;
  312.  
  313.     /* Add to the linked list. */
  314.     mtail->me_next = me;
  315.     mtail = me;
  316.     fsp++;
  317.       }
  318.   }
  319. #endif /* FS_STATFS */
  320.  
  321. #endif /* !atarist */
  322.   /* Free the dummy head. */
  323.   me = mount_list;
  324.   mount_list = mount_list->me_next;
  325.   free (me);
  326.   return mount_list;
  327. }
  328.  
  329. /* Fill in the fields of FSP with information about space usage on
  330.    the filesystem on which PATH is a node.
  331.    Return 0 if successful, -1 if not. */
  332.  
  333. int
  334. get_fs_usage (path, fsp)
  335.      char *path;
  336.      struct fs_usage *fsp;
  337. {
  338.  
  339. /**
  340.  ** (sjk)++ Get the free space on a given file system...
  341.  **/
  342. #if defined(__atarist__)
  343.   int stats[4],device,bytes_per_cluster;
  344.  
  345.   if (path != NULL)   device = 1 + (int)(path[0] - 'A');
  346.     else device = 3;
  347.  
  348.   Dfree(stats,device);
  349.   bytes_per_cluster = stats[2]*stats[3];
  350.   fsp->fsu_blocks = (stats[1]*bytes_per_cluster)/1024;
  351.   fsp->fsu_bfree  = (stats[0]*bytes_per_cluster)/1024;
  352.   fsp->fsu_bavail = fsp->fsu_bfree;
  353.   fsp->fsu_files  = 0;
  354.   fsp->fsu_ffree  = 0;
  355. #else 
  356.  
  357. #ifdef FS_MNTENT
  358.   struct statfs fsd;
  359.  
  360.   if (statfs (path, &fsd) != 0)
  361.     return -1;
  362.   fsp->fsu_blocks = fsd.f_blocks;
  363.   fsp->fsu_bfree = fsd.f_bfree;
  364.   fsp->fsu_bavail = fsd.f_bavail;
  365.   fsp->fsu_files = fsd.f_files;
  366.   fsp->fsu_ffree = fsd.f_ffree;
  367. #endif /* FS_MNTENT */
  368.  
  369. #ifdef FS_USG_STATFS
  370. #define f_bavail f_bfree
  371.   struct statfs fsd;
  372.  
  373.   if (statfs (path, &fsd, sizeof fsd, 0) < 0)
  374.     return -1;
  375.   fsp->fsu_blocks = (fsd.f_blocks + 1) / 2;
  376.   fsp->fsu_bfree = (fsd.f_bfree + 1) / 2;
  377.   fsp->fsu_bavail = (fsd.f_bavail + 1) / 2;
  378.   fsp->fsu_files = fsd.f_files;
  379.   fsp->fsu_ffree = fsd.f_ffree;
  380. #endif
  381.  
  382. #ifdef FS_STATVFS
  383.   struct statvfs fsd;
  384.  
  385.   if (statvfs (path, &fsd) < 0)
  386.     return -1;
  387.   fsp->fsu_blocks = (fsd.f_blocks + 1) / (1024 / fsd.f_frsize);
  388.   fsp->fsu_bfree = (fsd.f_bfree + 1) / (1024 / fsd.f_frsize);
  389.   fsp->fsu_bavail = (fsd.f_bavail + 1) / (1024 / fsd.f_frsize);
  390.   fsp->fsu_files = fsd.f_files;
  391.   fsp->fsu_ffree = fsd.f_ffree;
  392. #endif
  393.  
  394. #ifdef FS_STATFS
  395.   struct statfs fsd;
  396.  
  397.   if (statfs (path, &fsd) < 0)
  398.     return -1;
  399.   fsp->fsu_blocks = (fsd.f_blocks + 1) / (1024 / fsd.f_fsize);
  400.   fsp->fsu_bfree = (fsd.f_bfree + 1) / (1024 / fsd.f_fsize);
  401.   fsp->fsu_bavail = (fsd.f_bavail + 1) / (1024 / fsd.f_fsize);
  402.   fsp->fsu_files = fsd.f_files;
  403.   fsp->fsu_ffree = fsd.f_ffree;
  404. #endif
  405.  
  406. #ifdef FS_GETMNT
  407.   struct fs_data fsd;
  408.  
  409.   if (statfs (path, &fsd) != 1)
  410.     return -1;
  411.   fsp->fsu_blocks = fsd.fd_req.btot;
  412.   fsp->fsu_bfree = fsd.fd_req.bfree;
  413.   fsp->fsu_bavail = fsd.fd_req.bfreen;
  414.   fsp->fsu_files = fsd.fd_req.gtot;
  415.   fsp->fsu_ffree = fsd.fd_req.gfree;
  416. #endif /* FS_GETMNT */
  417.  
  418. #endif /* ! atari st */
  419.   return 0;
  420. }
  421.  
  422. /* Return the value of the hexadecimal number represented by CP.
  423.    No prefix (like '0x') or suffix (like 'h') is expected to be
  424.    part of CP. */
  425.  
  426. int
  427. xatoi (cp)
  428.      char *cp;
  429. {
  430.   int val;
  431.   
  432.   val = 0;
  433.   while (*cp)
  434.     {
  435.       if (*cp >= 'a' && *cp <= 'f')
  436.     val = val * 16 + *cp - 'a' + 10;
  437.       else if (*cp >= 'A' && *cp <= 'F')
  438.     val = val * 16 + *cp - 'A' + 10;
  439.       else if (*cp >= '0' && *cp <= '9')
  440.     val = val * 16 + *cp - '0';
  441.       else
  442.     break;
  443.       cp++;
  444.     }
  445.   return val;
  446. }
  447.